home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.4d7 source
/
tn3270
/
writetm.c
< prev
Wrap
Text File
|
1992-04-17
|
15KB
|
646 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.4d7 April, 1992
* Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#if !defined(USEDUMP)
#include "maclib.h"
#include "termdef.h"
#include "tn3270funcs.h"
#include "globals.h"
#else
#pragma load "tn3270DumpFile"
#endif
#pragma segment 3270seg1
extern unsigned char ordertab[];
void writetm(unsigned char *cmd, short len, char init, cnr *cp)
{
register short left;
register short size;
register unsigned char c, ew;
cp->savedvalid = 0; /* getattr saved info. may be invalid now */
if (init) {
ew = 0; /* erase/write flag */
if ((cmd[0] & 0x07) >= 5) { /* interpret op-code */
ew = 1;
if (cp->skipnewmode == 0) {
if (((cmd[0] & 0x0f) == 0x0d) || (cmd[0] == 0x7e)) { /* ewa */
cp->ewamode = 1;
}
else { /* possible end of ewa */
cp->ewamode = 0;
}
newmode(cp->ewamode, 0, cp);
}
clrscn(cp);
}
intwcc(ew, cmd[1], cp); /* interpret WCC */
cp->ldvoff = 2; /* skip to start of data */
cp->ptfill = 0;
cp->chratr = 0;
cp->bufadr = cp->curadr; /* buffer address starts out at cursor */
}
while (cp->ldvoff < len) {
/* special code to handle data quickly */
c = cmd[cp->ldvoff++];
if (ordertab[c]) {
(cp->chrbuff)[cp->bufadr] = c;
(cp->atrbuff)[cp->bufadr] = cp->chratr;
if ((c == 0xad) || (c == 0xbd))
if (cp->fixbracket) (cp->atrbuff)[cp->bufadr] += 0x4000;
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
cp->ptfill = 1;
continue;
}
else cp->ldvoff--;
/* order processing code */
left = len - cp->ldvoff;
switch(cmd[cp->ldvoff]) {
case 0x1D: /* Start Field */
if (left < 2) return;
intsf(cmd[cp->ldvoff+1], cp);
cp->ldvoff += 2;
cp->ptfill = 0;
break;
case 0x11: /* Set Buffer Address */
if (left < 3) return;
intsba(cmd[cp->ldvoff+1], cmd[cp->ldvoff+2], cp);
cp->ldvoff += 3;
cp->ptfill = 0;
break;
case 0x13: /* Insert Cursor */
intic(cp);
cp->ldvoff++;
cp->ptfill = 0;
break;
case 0x05: /* Program Tab */
intpt(cp);
cp->ldvoff++;
break;
case 0x3C: /* Repeat to Address */
if (left < 4) return;
c = cmd[cp->ldvoff+3];
if (c == 0x08) {
if (left < 5) return;
c = cmd[cp->ldvoff+4];
intra(cmd[cp->ldvoff+1], cmd[cp->ldvoff+2], c, 1, cp);
cp->ldvoff += 5;
}
else {
intra(cmd[cp->ldvoff+1], cmd[cp->ldvoff+2], c, 0, cp);
cp->ldvoff += 4;
}
cp->ptfill = 0;
break;
case 0x12: /* Erase Unprotected to Address */
if (left < 3) return;
inteua(cmd[cp->ldvoff+1], cmd[cp->ldvoff+2], cp);
cp->ldvoff += 3;
cp->ptfill = 0;
break;
case 0x08: /* Graphics Escape */
if (left < 2) return;
intdata(cmd[cp->ldvoff+1], 1, cp);
cp->ldvoff += 2;
break;
case 0x29: /* Start Field Extended */
if (left < 2) return;
size = (cmd[cp->ldvoff+1]+1) * 2;
if (left < size) return;
intsfe(cmd+cp->ldvoff+2, cmd[cp->ldvoff+1], cp);
cp->ldvoff += size;
cp->ptfill = 0;
break;
case 0x2C: /* Modify Field */
if (left < 2) return;
size = (cmd[cp->ldvoff+1]+1) * 2;
if (left < size) return;
intmf(cmd+cp->ldvoff+2, cmd[cp->ldvoff+1], cp);
cp->ldvoff += size;
cp->ptfill = 0;
break;
case 0x28: /* Set Attribute */
if (left < 3) return;
intsa(cmd[cp->ldvoff+1], cmd[cp->ldvoff+2], cp);
cp->ldvoff += 3;
cp->ptfill = 0;
break;
default: /* shouldn't happen */
break;
}
}
}
void clrscn(cnr *cp)
{
memset(cp->chrbuff, 0, cp->maxcnt);
memset(cp->atrbuff, 0, cp->maxcnt<<1);
cp->curadr = 0;
cp->bufadr = 0;
cp->colorfield = 0;
cp->textsel = 0;
cp->fmtscrn = 0;
}
void intwcc(unsigned char ew, unsigned char wcc, cnr *cp)
{
register short i;
cp->lastwcc = wcc & 0x7f;
if (wcc & 0x01) for (i=0; i < cp->maxcnt; i++) {
(cp->atrbuff)[i] &= 0xFEFF;
}
cp->kb_err = 0;
if (cp->kblock) {
cp->lastwcc |= 0x80; /* remember was locked */
/* indicate SYSTEM immediately */
if ((cp->kblcode == 2) && ((wcc & 0x02) == 0)) {
cp->kblcode = 1;
newstat(cp);
}
}
else {
cp->kblock = 1;
cp->kblcode = 2;
newstat(cp);
}
if (ew) if (wcc & 0x40) /* wcc reset in EW/EWA */
clrpict(cp); /* erase graphics */
}
void endwcc(cnr *cp)
{
if (cp->lastwcc & 0x04) if (!(cp->tcpflg)) beep(cp);
else cp->pndbeep = 1;
if (cp->lastwcc & 0x02) cp->rdaid = 0x60; /* reset last AID */
if (cp->cs.curpos) {
cp->x = cp->curadr%cp->scrhsize;
cp->y = cp->curadr/cp->scrhsize;
}
if ((cp->lastwcc & 0x82) != 0x80) {
cp->kblock = 0;
cp->kblcode = 0;
newstat(cp);
}
else if (cp->cs.curpos) newstat(cp);
checkfmt(cp); /* check that fmtscrn is still correct */
}
void checkfmt(cnr *cp) /* check all attributes have not been overwritten by data */
{
register short i;
/* unformatted is always correct */
if (cp->fmtscrn == 0) return;
/* formatted if attribute where we last put one */
if ((cp->atrbuff)[cp->attrloc] & 0x8000) return;
/* else look for an attribute byte */
for (i=0; i < cp->maxcnt; i++)
if ((cp->atrbuff)[i] & 0x8000) return;
/* all attributes were overwritten: reset flag */
cp->fmtscrn = 0;
}
void intsf(unsigned char attr, cnr *cp)
{
(cp->chrbuff)[cp->bufadr] = 0x1d;
(cp->atrbuff)[cp->bufadr] = 0x8000 + ((attr & 0x3f) << 8);
cp->attrloc = cp->bufadr;
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
cp->fmtscrn = 1;
}
void intsba(unsigned char a1, unsigned char a2, cnr *cp)
{
cp->bufadr = cvtadr(a1, a2, cp);
}
void intic(cnr *cp)
{
cp->curadr = cp->bufadr;
}
void intpt(cnr *cp)
{
register unsigned short a;
while (true) { /* loop through protected fields */
while (!((cp->atrbuff)[cp->bufadr] & 0x8000)) { /* get to next attribute */
if (cp->ptfill) setnull(cp); /* fill with nulls if set */
else {
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
}
if (cp->bufadr == 0) return;
}
cp->ptfill = 0; /* no nulls after first field */
a = (cp->atrbuff)[cp->bufadr]; /* get attributes for this field */
cp->bufadr++; /* increment buffer address */
if (cp->bufadr == cp->maxcnt) {
cp->bufadr = 0; /* done if wrapped */
return;
}
if (!(a & 0x2000)) return; /* found field if unprotected */
}
}
void intra(unsigned char a1, unsigned char a2,
unsigned char c, unsigned char g, cnr *cp)
{
register short endadr;
endadr = cvtadr(a1, a2, cp);
do intdata(c, g, cp); while (endadr != cp->bufadr);
}
void inteua(unsigned char a1, unsigned char a2, cnr *cp)
{
register unsigned char skip, nofmt;
register short endadr, addr, prot;
endadr = cvtadr(a1, a2, cp);
addr = cp->bufadr; /* find previous attribute */
nofmt = 0;
while (!((cp->atrbuff)[addr] & 0x8000)) {
if (addr == 0) {
nofmt = 1;
break;
}
else addr--;
}
if (nofmt) prot = 0;
else prot = (cp->atrbuff)[addr] & 0x2000;
skip = 0;
do {
if ((cp->atrbuff)[cp->bufadr] & 0x8000) {
prot = (cp->atrbuff)[cp->bufadr] & 0x2000;
skip = 1;
}
else if (!prot) {
if (skip) {
skip = 0;
}
setnull(cp);
}
else skip = 1;
if (skip) {
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
}
} while (endadr != cp->bufadr);
}
void intsfe(unsigned char *field, unsigned char pairs, cnr *cp)
{
(cp->atrbuff)[cp->bufadr] = intpairs(0x8000, field, pairs, cp);
(cp->chrbuff)[cp->bufadr] = 0x1d;
cp->attrloc = cp->bufadr;
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
cp->fmtscrn = 1;
}
void intmf(unsigned char *field, unsigned char pairs, cnr *cp)
{
register short atr;
atr = intpairs((cp->atrbuff)[cp->bufadr], field, pairs, cp);
if (atr & 0x8000) {
(cp->atrbuff)[cp->bufadr] = atr;
(cp->chrbuff)[cp->bufadr] = 0x1d;
}
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
}
void intsa(unsigned char type, unsigned char value, cnr *cp)
{
register unsigned char safield[2];
if ((type == 0) && (value == 0)) {
cp->chratr = 0;
return;
}
safield[0] = type;
safield[1] = value;
cp->chratr = intpairs(cp->chratr, safield, 1, cp);
}
unsigned short intpairs(unsigned short atr, unsigned char *field,
unsigned char pairs, cnr *cp)
{
register unsigned char c;
register short offset;
offset = 0;
while (pairs > 0) {
c = field[offset+1];
switch(field[offset]) {
case 0xC0: atr &= 0xC0FF;
atr += (c & 0x3f) << 8;
break;
case 0x41: atr &= 0xFFE7;
if (c == 0xF4) c = 0xF3;
atr += (c & 0x03) << 3;
break;
case 0x42: atr &= 0xFFF8;
if ((c & 0x07) == 0) break;
/* if (c == 0) c = 0xF4; */
atr += c & 0x07;
cp->colorfield = 1;
break;
case 0x43: atr &= 0xFF3F;
atr += (c & 0x03) << 6;
break;
default: break;
}
offset += 2;
pairs--;
}
return(atr);
}
void intdata(unsigned char code, unsigned char geflag, cnr *cp)
{
(cp->chrbuff)[cp->bufadr] = code;
(cp->atrbuff)[cp->bufadr] = cp->chratr;
if ((code == 0xad) || (code == 0xbd))
if (cp->fixbracket) geflag = 1;
if (geflag) (cp->atrbuff)[cp->bufadr] += 0x4000;
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
}
void setnull(cnr *cp)
{
(cp->chrbuff)[cp->bufadr] = 0;
(cp->atrbuff)[cp->bufadr] = 0;
cp->bufadr++;
if (cp->bufadr == cp->maxcnt) cp->bufadr = 0;
}
short cvtadr(unsigned char a1, unsigned char a2, cnr *cp)
{
short a;
if ((a1 & 0xc0) == 0) /* 14-bit address */
a = (a1 << 8) + a2;
else a = ((a1 & 0x3f) << 6) + (a2 & 0x3f); /* 12-bit address */
if (a < 0) a = 0;
if (a > cp->maxoff) a = cp->maxoff;
return(a);
}
void orderinit(void)
{
register short i, j;
static unsigned char ordercodes[] =
{0x1d, 0x11, 0x13, 0x05, 0x3c, 0x12, 0x08, 0x29, 0x2c, 0x28, 0x00};
for (i=0; i < 256; i++) ordertab[i] = 0xff;
j = strlen(ordercodes);
for (i=0; i < j; i++) ordertab[ordercodes[i]] = 0;
}
void setrectsel(short offset1, short offset2, cnr *cp)
{
short rowmin, rowmax, colmin, colmax, t;
register short row, col;
if (offset1 == offset2) return;
rowmin = offset1 / cp->scrhsize;
colmin = offset1 % cp->scrhsize;
rowmax = offset2 / cp->scrhsize;
colmax = offset2 % cp->scrhsize;
if (rowmin > rowmax) {
t = rowmax;
rowmax = rowmin;
rowmin = t;
}
if (colmin > colmax) {
t = colmax;
colmax = colmin;
colmin = t;
}
for (row = rowmin; row <= rowmax; row++)
for (col = colmin; col <= colmax; col++) {
if ((cp->atrbuff)[cp->scrhsize*row + col] ^= 0x0020) cp->textsel = 1;
}
invldscr(cp);
}
void settextsel(short offset1, short offset2, char invert, cnr *cp)
{
short start, end, offset;
start = offset1;
end = offset2;
if (end < start) {
start = offset2;
end = offset1;
}
for (offset = start; offset < end; offset++) {
if (invert) {
(cp->atrbuff)[offset] ^= 0x0020;
}
else {
(cp->atrbuff)[offset] |= 0x0020;
}
cp->textsel = 1;
}
invldscr(cp);
}
void addfieldsel(cnr *cp) /* select entire field for any field partly selected */
{
register short i;
short firstpos, attrpos;
char selflag;
if (!(cp->fmtscrn)) return;
firstpos = 0;
/* if first byte not an attribute, find attribute for first byte */
if (((cp->atrbuff)[0] & 0x8000) == 0) {
firstpos = -1;
for (i = cp->maxoff; i > 0; i--)
if ((cp->atrbuff)[i] & 0x8000) {
firstpos = i;
break;
}
}
if (firstpos < 0) return;
/* set selection bit for the attribute byte of each field to be selected */
attrpos = firstpos;
for (i=0; i < cp->maxcnt; i++)
if ((cp->atrbuff)[i] & 0x8000) { /* attribute byte */
attrpos = i;
}
else { /* data byte */
if ((cp->atrbuff)[i] & 0x0020) (cp->atrbuff)[attrpos] |= 0x0020;
}
/* set selections bits for all bytes in selected fields */
selflag = ((cp->atrbuff)[firstpos] & 0x0020) == 0x0020;
for (i=0; i < cp->maxcnt; i++)
if ((cp->atrbuff)[i] & 0x8000) { /* attribute byte */
selflag = ((cp->atrbuff)[i] & 0x0020) == 0x0020;
}
else {
if (selflag) (cp->atrbuff)[i] |= 0x0020;
}
/* reset selection bits in the field attributes */
for (i=0; i < cp->maxcnt; i++)
if ((cp->atrbuff)[i] & 0x8000) (cp->atrbuff)[i] &= 0xffdf;
}
void resetsel(cnr *cp)
{
register short i;
char selflag;
selflag = 0;
for (i = 0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[i] & 0x0020) {
selflag = 1;
(cp->atrbuff)[i] &= 0xffdf;
}
}
cp->textsel = 0;
if (selflag) invldscr(cp);
}
void checksel(cnr *cp) /* check if there really is selected text */
{
register short i;
cp->textsel = 0;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[i] & 0x0020) {
cp->textsel = 1;
return;
}
}
}
/* find new starting point for extending text selection */
void addsel(short *downloc, cnr *cp)
{
short startoff, endoff;
register short i;
for (i=0; i < cp->maxcnt; i++) /* get first selection offset */
if ((cp->atrbuff)[i] & 0x0020) {
startoff = i;
break;
}
for (i=cp->maxoff; i >= 0; i--)
if ((cp->atrbuff)[i] & 0x0020) {
endoff = i;
break;
}
if ((*downloc) < startoff)
(*downloc) = endoff + 1;
else (*downloc) = startoff;
}
void wordadj(short *loc1, short *loc2, char endadj, cnr *cp)
{
short startloc, endloc;
short startline, endline;
char swapped;
swapped = 0;
startloc = *loc1;
endloc = *loc2;
if (startloc > endloc) {
startloc = *loc2;
endloc = *loc1;
swapped = 1;
}
endloc -= endadj;
if (endloc < 0) return;
startline = startloc/cp->scrhsize;
endline = endloc/cp->scrhsize;
while ((!atspace(startloc, cp)) && (startloc > 0) &&
((startloc-1)/cp->scrhsize == startline)) startloc--;
while ((atspace(startloc, cp)) && (startloc < endloc) &&
((startloc+1)/cp->scrhsize <= endline)) startloc++;
while ((!atspace(endloc, cp)) && (endloc < cp->maxoff) &&
((endloc+1)/cp->scrhsize == endline)) endloc++;
while ((atspace(endloc, cp)) && (endloc > startloc) &&
((endloc-1)/cp->scrhsize >= startline)) endloc--;
if (atspace(startloc, cp) && atspace(endloc, cp)) return;
endloc += endadj;
if (swapped) {
*loc2 = startloc;
*loc1 = endloc;
}
else {
*loc1 = startloc;
*loc2 = endloc;
}
}
short atspace(short loc, cnr *cp)
{
if ((cp->chrbuff)[loc] == 0x40) return(1);
if ((cp->chrbuff)[loc] == 0x00) return(1);
if ((cp->atrbuff)[loc] & 0x8000) return(1);
return(0);
}